//
// Created by wxd on 2025/8/31.
//

#pragma once

#ifndef ENCODERUTILS_H
#define ENCODERUTILS_H

#include <cstdint>
#include <string>

// FNV-1a 32位哈希
inline uint32_t fnv1a32(const std::string& str) {
    const uint32_t prime = 0x01000193; // 16777619
    uint32_t hash = 0x811C9DC5;        // 2166136261

    for (char c : str) {
        hash ^= static_cast<uint8_t>(c);
        hash *= prime;
    }
    return hash;
}

// FNV-1a 64位哈希
inline uint64_t fnv1a64(const std::string& str) {
    const uint64_t prime = 0x00000100000001B3; // 1099511628211
    uint64_t hash = 0xCBF29CE484222325;        // 14695981039346656037

    for (char c : str) {
        hash ^= static_cast<uint8_t>(c);
        hash *= prime;
    }
    return hash;
}

// MurmurHash3 32位版本
inline uint32_t murmurHash3_32(const std::string& str, uint32_t seed = 0) {
    const uint8_t* data = reinterpret_cast<const uint8_t*>(str.data());
    const size_t len = str.length();
    const size_t nblocks = len / 4;

    uint32_t h1 = seed;
    const uint32_t c1 = 0xcc9e2d51;
    const uint32_t c2 = 0x1b873593;

    // 处理4字节块
    const uint32_t* blocks = reinterpret_cast<const uint32_t*>(data + nblocks * 4);
    for (int i = -nblocks; i; i++) {
        uint32_t k1 = blocks[i];

        k1 *= c1;
        k1 = (k1 << 15) | (k1 >> 17);
        k1 *= c2;

        h1 ^= k1;
        h1 = (h1 << 13) | (h1 >> 19);
        h1 = h1 * 5 + 0xe6546b64;
    }

    // 处理剩余字节
    const uint8_t* tail = data + nblocks * 4;
    uint32_t k1 = 0;

    switch (len & 3) {
        case 3: k1 ^= tail[2] << 16;
        case 2: k1 ^= tail[1] << 8;
        case 1: k1 ^= tail[0];
            k1 *= c1;
            k1 = (k1 << 15) | (k1 >> 17);
            k1 *= c2;
            h1 ^= k1;
        default: break;
    }

    // 最终混合
    h1 ^= len;
    h1 ^= h1 >> 16;
    h1 *= 0x85ebca6b;
    h1 ^= h1 >> 13;
    h1 *= 0xc2b2ae35;
    h1 ^= h1 >> 16;

    return h1;
}

#endif //ENCODERUTILS_H
